package framework.model;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import framework.utils.dto.Challenge;

/**
 * This class contains information about the lobby
 * @author Stephan Veenstra
 * @version 0.1
 */
public class LobbyModel extends Model {

	private ArrayList<Challenge> challenges;
	private ArrayList<String> players, games;
	private boolean inGame;
	
	public LobbyModel(){
		this.players 	= new ArrayList<String>();
		this.games   	= new ArrayList<String>();
		this.challenges = new ArrayList<Challenge>();
		this.setInGame(false);
	}
	
	/**
	 * Clears the challengers list
	 */
	public void clearChallenges(){
		this.challenges = new ArrayList<Challenge>();
		dispatchEvent(new ActionEvent(this,0,"challenge_updated"));
	}
	
	/**
	 * Add a challenge to the list
	 * @param playername
	 * @param gametype
	 * @param challengeID
	 */
	public void addChallenge(String playername, String gametype, int challengeID) {
		this.challenges.add(new Challenge(playername, gametype, challengeID));
		super.dispatchEvent(new ActionEvent(this,0,"challenge_updated"));
	}
	
	/**
	 * Add a challenge to the list
	 * @param challenge
	 */
	public void addChallenge(Challenge challenge){
		this.challenges.add(challenge);
		super.dispatchEvent(new ActionEvent(this,0,"challenge_updated"));
	}
	
	/**
	 * Remove a specific challenge by it's ID
	 * @param id
	 */
	public void removeChallengeByID(int id){
		Challenge c = getChallengeByID(id);
		if(c != null){
			this.challenges.remove(c);
			dispatchEvent(new ActionEvent(this,0,"challenge_updated"));
		}
	}
	
	/**
	 * Remove challenge from list 
	 * @method removeChallenge
	 * @param <Challenge> challenge
	 */
	public void removeChallenge(Challenge challenge) {
		int index = this.challenges.indexOf(challenge);
		if(index > -1) {
			this.challenges.remove(index);
			super.dispatchEvent(new ActionEvent(this,0,"challenge_updated"));
		}
	};
	
	/**
	 * return a challenge by it's ID
	 * @param id
	 * @return The Challenge with the given ID if found, else null
	 */
	public Challenge getChallengeByID(int id){
		for(Challenge c : challenges){
			if(c.getChallengeID() == id){
				return c;
			}
		}
		return null;
	}
	
	/**
	 * Returns the list of challenges
	 * @return
	 */
	public List<Challenge> getChallenges() {
		return this.challenges;
	}
	
	/**********************
	 *** SETTER METHODS ***
	 *********************/
	
	/**
	 * @method setInGame
	 * @param <boolean> inGame
	 */
	public void setInGame(boolean inGame) {
		this.inGame = inGame;
		super.dispatchEvent(new ActionEvent(this,0,"game_updated"));
	};
	 
	/**
	 * Add single player to list
	 * @method setPlayer
	 * @param <String> player
	 */
	public void setPlayer(String player) {
		this.players.add(player);
		super.dispatchEvent(new ActionEvent(this,0,"players_updated"));
	};
	
	/**
	 * Add multiple players to list
	 * @method setPlayers
	 * @param <ArrayList<String>> players
	 */
	public void setPlayers(ArrayList<String> players) {
		this.players.addAll(players);
		this.dispatchEvent(new ActionEvent(this,0,"players_updated"));		
	};
	
	/**
	 * Add single player to list
	 * @method setGame
	 * @param <String> game
	 */
	public void setGame(String game) {
		this.games.add(game);
		super.dispatchEvent(new ActionEvent(this,0,"games_updated"));
	};
	
	/**
	 * Add multiple games to list
	 * @method setGames
	 * @param <ArrayList<String>> games
	 */
	public void setGames(ArrayList<String> games) {
		this.games.addAll(games);
		this.dispatchEvent(new ActionEvent(this,0,"games_updated"));		
	};
	
	/**********************
	 *** GETTER METHODS ***
	 *********************/
	
	/**
	 * @method isInGame
	 * @return <boolean> inGame
	 */
	public boolean isInGame() {
		return this.inGame;
	};
	
	/**
	 * @method getPlayers
	 * @return <ArrayList<String>> players
	 */
	public ArrayList<String> getPlayers() {
		return this.players;
	};
	
	/**
	 * @method getGames
	 * @return <ArrayList<String>> games
	 */
	public ArrayList<String> getGames() {
		return this.games;
	};
	
	
}
